package com.tencent.wxcloudrun.service.business.fangdong;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.PhoneUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tencent.wxcloudrun.config.CustomException;
import com.tencent.wxcloudrun.config.UserContext;
import com.tencent.wxcloudrun.pojo.bo.MediaInfo;
import com.tencent.wxcloudrun.pojo.bo.NoticeConstant;
import com.tencent.wxcloudrun.pojo.dto.req.ApplyLandlordReq;
import com.tencent.wxcloudrun.pojo.dto.resp.GetApplyPageResp;
import com.tencent.wxcloudrun.pojo.dto.resp.PersonInfoResp;
import com.tencent.wxcloudrun.pojo.po.XApplyLand;
import com.tencent.wxcloudrun.pojo.po.XPersonInfo;
import com.tencent.wxcloudrun.service.XApplyLandService;
import com.tencent.wxcloudrun.service.XPersonInfoService;
import com.tencent.wxcloudrun.service.business.NoticeService;
import com.tencent.wxcloudrun.util.IdUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
public class PersonService {

    @Resource
    private NoticeService noticeService;

    @Resource
    private XPersonInfoService xPersonInfoService;

    @Resource
    private XApplyLandService xApplyLandService;

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    public String isLandlord() {
        String openId = UserContext.getOpenId();
        log.info(">>>>>> 发现有用户进入房东首页，检查此用户是否已经是房东或助理。 {}", openId);
        String check = redisTemplate.opsForValue().get("identity_" + openId);
        log.info(">>>>>> 先检查redis中是否有相关信息  " + check);
        if (StrUtil.isNotBlank(check) && "landlord".equals(check)) {
            return "yes";
        }
        if (StrUtil.isNotBlank(check) && "tenant".equals(check)) {
            return "no";
        }
        log.info(">>>>>> 未从redis中找到当前用户的身份信息，开始查表。");
        LambdaQueryWrapper<XPersonInfo> xPersonInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xPersonInfoLambdaQueryWrapper.eq(XPersonInfo::getPersonId, openId);
        List<XPersonInfo> allList = xPersonInfoService.list(xPersonInfoLambdaQueryWrapper);
        if (CollUtil.isEmpty(allList)) {
            log.info(">>>>>> 正常情况下不会进入此逻辑。");
            return "no";
        }
        List<XPersonInfo> collect = allList.stream().filter(var -> "landlord".equals(var.getPersonType()) ||
                "helpmate".equals(var.getPersonType()) ||
                "admin".equals(var.getPersonType())).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(collect)) {
            log.info(">>>>>> 当前用户有房东或助理身份。");
            redisTemplate.opsForValue().set("identity_" + openId, "landlord", 5, TimeUnit.MINUTES);
            return "yes";
        }
        log.info(">>>>>> 当前用户没有房东或助理身份。");
        redisTemplate.opsForValue().set("identity_" + openId, "tenant", 5, TimeUnit.MINUTES);
        return "no";
    }

    public PersonInfoResp getInfo() {
        String openId = UserContext.getOpenId();
        log.info(">>>>>> 进入房东个人信息页，查询数据用于展示");
        LambdaQueryWrapper<XPersonInfo> xPersonInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xPersonInfoLambdaQueryWrapper.eq(XPersonInfo::getPersonId, openId);
        xPersonInfoLambdaQueryWrapper.eq(XPersonInfo::getPersonType, "landlord");
        XPersonInfo landlord = xPersonInfoService.getOne(xPersonInfoLambdaQueryWrapper);
        PersonInfoResp personInfoResp = new PersonInfoResp();
        if (ObjUtil.isEmpty(landlord) || StrUtil.isBlank(landlord.getPersonId())) {
            return personInfoResp;
        }
        personInfoResp.setHousePic(JSON.parseArray(landlord.getHousePic(), MediaInfo.class));
        personInfoResp.setLeasePic(JSON.parseArray(landlord.getLeasePic(), MediaInfo.class));
        personInfoResp.setCardZheng(JSON.parseObject(landlord.getCardFront(), MediaInfo.class));
        personInfoResp.setCardFan(JSON.parseObject(landlord.getCardBack(), MediaInfo.class));
        personInfoResp.setSignPic(JSON.parseObject(landlord.getSignPic(), MediaInfo.class));
        personInfoResp.setName(landlord.getCardName());
        personInfoResp.setTel(landlord.getPhone());
        personInfoResp.setSex(landlord.getSex());
        personInfoResp.setIdCard(landlord.getCardId());
        return personInfoResp;
    }

    @Transactional(rollbackFor = Exception.class)
    public String applyLandlord(ApplyLandlordReq req) {
        Date date = new Date();
        String openId = UserContext.getOpenId();
        log.info(">>>>>> 发现有用户在进行房东申请操作。 {}", openId);
        XApplyLand xApplyLand = new XApplyLand();
        if (!PhoneUtil.isMobile(req.getTel())) {
            throw new CustomException("手机号码非法，请检查！");
        }
        xApplyLand.setTel(req.getTel());
        xApplyLand.setStatus("1");
        xApplyLand.setFailInfo("");
        LambdaQueryWrapper<XApplyLand> xApplyLandLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xApplyLandLambdaQueryWrapper.eq(XApplyLand::getOpenId, openId);
        XApplyLand oneByOpenId = xApplyLandService.getOne(xApplyLandLambdaQueryWrapper);
        if (CollUtil.isEmpty(req.getHousePic()) && ObjectUtil.isNotNull(oneByOpenId)) {
            xApplyLand.setHousePic(oneByOpenId.getHousePic());
        } else {
            xApplyLand.setHousePic(CollUtil.isEmpty(req.getHousePic()) ? "" : MediaInfo.transMediaListToStr(req.getHousePic()));
        }
        if (CollUtil.isEmpty(req.getLeasePic()) && ObjectUtil.isNotNull(oneByOpenId)) {
            xApplyLand.setLeasePic(oneByOpenId.getLeasePic());
        } else {
            xApplyLand.setLeasePic(CollUtil.isEmpty(req.getLeasePic()) ? "" : MediaInfo.transMediaListToStr(req.getLeasePic()));
        }
        if (ObjUtil.isEmpty(req.getCardZheng()) || StrUtil.isBlank(req.getCardZheng().getFileID())) {
            xApplyLand.setCardZheng(oneByOpenId.getCardZheng());
        } else {
            xApplyLand.setCardZheng(MediaInfo.transMediaListToStr(req.getCardZheng()));
        }
        if (ObjUtil.isEmpty(req.getCardFan()) || StrUtil.isBlank(req.getCardFan().getFileID())) {
            xApplyLand.setCardFan(oneByOpenId.getCardFan());
        } else {
            xApplyLand.setCardFan(MediaInfo.transMediaListToStr(req.getCardFan()));
        }
        if (ObjUtil.isEmpty(req.getSignPic()) || StrUtil.isBlank(req.getSignPic().getFileID())) {
            xApplyLand.setSignPic(oneByOpenId.getSignPic());
        } else {
            xApplyLand.setSignPic(MediaInfo.transMediaListToStr(req.getSignPic()));
        }
        if (ObjUtil.isEmpty(oneByOpenId) || StrUtil.isBlank(oneByOpenId.getApplyId())) {
            log.info(">>>>>> 没有发起过审批---把审批信息记录到 x_apply_land 表，设置审批状态为审批中。");
            xApplyLand.setApplyId(IdUtil.generateId());
            xApplyLand.setOpenId(openId);
            xApplyLand.setCreateTime(date);
            xApplyLand.setUpdateTime(date);
            xApplyLandService.save(xApplyLand);
            // 生成一个通知
            noticeService.createNotice("land", NoticeConstant.BE_LAND_TITLE,
                    String.format(NoticeConstant.BE_LAND_CONTENT, DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN)));
            return "success";
        }
        if ("3".equals(oneByOpenId.getStatus())) {
            throw new CustomException("正常状态下不能操作");
        }
        if ("1".equals(oneByOpenId.getStatus())) {
            throw new CustomException("审批中，不能操作！");
        }
        log.info(">>>>>>前一次审批失败了。");
        xApplyLand.setFailInfo(oneByOpenId.getFailInfo());
        xApplyLand.setUpdateTime(date);
        xApplyLand.setId(oneByOpenId.getId());
        xApplyLandService.updateById(xApplyLand);
        // 生成一个通知
        noticeService.createNotice("land", NoticeConstant.BE_LAND_TITLE,
                String.format(NoticeConstant.BE_LAND_CONTENT, DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN)));
        return "success";
    }

    public GetApplyPageResp getApplyPage() {
        String openId = UserContext.getOpenId();
        GetApplyPageResp resp = new GetApplyPageResp();
        LambdaQueryWrapper<XApplyLand> xApplyLandLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xApplyLandLambdaQueryWrapper.eq(XApplyLand::getOpenId, openId);
        XApplyLand oneByOpenId = xApplyLandService.getOne(xApplyLandLambdaQueryWrapper);
        if (ObjUtil.isEmpty(oneByOpenId) || StrUtil.isBlank(oneByOpenId.getOpenId())) {
            log.info(">>>>>>属于是还没发起过审批。");
            return resp;
        }
        if ("3".equals(oneByOpenId.getStatus())) {
            throw new CustomException("当房东用户处于正常情况下时不能调用此接口。");
        }
        if (StrUtil.isNotBlank(oneByOpenId.getHousePic())) {
            resp.setHousePic(JSON.parseArray(oneByOpenId.getHousePic(), MediaInfo.class));
        }
        if (StrUtil.isNotBlank(oneByOpenId.getLeasePic())) {
            resp.setLeasePic(JSON.parseArray(oneByOpenId.getLeasePic(), MediaInfo.class));
        }
        if (StrUtil.isNotBlank(oneByOpenId.getCardZheng())) {
            resp.setCardZheng(JSON.parseObject(oneByOpenId.getCardZheng(), MediaInfo.class));
        }
        if (StrUtil.isNotBlank(oneByOpenId.getCardFan())) {
            resp.setCardFan(JSON.parseObject(oneByOpenId.getCardFan(), MediaInfo.class));
        }
        if (StrUtil.isNotBlank(oneByOpenId.getSignPic())) {
            resp.setSignPic(JSON.parseObject(oneByOpenId.getSignPic(), MediaInfo.class));
        }
        resp.setTel(oneByOpenId.getTel());
        if ("1".equals(oneByOpenId.getStatus())) {
            resp.setInfo("审批中");
        }
        if ("2".equals(oneByOpenId.getStatus())) {
            resp.setInfo(oneByOpenId.getFailInfo());
        }
        return resp;
    }

    @Transactional(rollbackFor = Exception.class)
    public String updateTel(String newTel) {
        Date date = new Date();
        String openId = UserContext.getOpenId();
        XApplyLand xApplyLand = new XApplyLand();
        xApplyLand.setOpenId(openId);
        xApplyLand.setTel(newTel);
        xApplyLand.setUpdateTime(date);
        LambdaQueryWrapper<XApplyLand> xApplyLandLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xApplyLandLambdaQueryWrapper.eq(XApplyLand::getOpenId, openId);
        xApplyLandService.update(xApplyLand, xApplyLandLambdaQueryWrapper);
        XPersonInfo xPersonInfo = new XPersonInfo();
        xPersonInfo.setPersonId(openId);
        xPersonInfo.setPhone(newTel);
        xPersonInfo.setUpdateTime(date);
        LambdaQueryWrapper<XPersonInfo> xPersonInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xPersonInfoLambdaQueryWrapper.eq(XPersonInfo::getPersonId, openId);
        xPersonInfoLambdaQueryWrapper.eq(XPersonInfo::getPersonType, "landlord");
        xPersonInfoService.update(xPersonInfo, xPersonInfoLambdaQueryWrapper);
        return "success";
    }
}
